为什么将面向数据编程更新到 1.1 版?

我们刚刚完成了关于 Java 中面向数据编程 1.1 版的六部分、七千字的文章系列,深入探讨了该范式以及最适合用于实现它的语言特性。不过,它留下了一个问题没有回答:为什么我们需要更新到 1.1 版?它希望在哪些方面改进最初的提案?以及作为后续问题:1.1 版有哪些缺点,1.2 版可以做得更好吗?我将在本文中分享我对这些问题的看法。😃

1.0 版

Brian Goetz 在其开创性的文章Java 中的面向数据编程中阐述了这四项指导原则

  • 对数据进行建模,对所有数据进行建模,并且只对数据进行建模。
  • 数据是不可变的。
  • 使非法状态不可表示。
  • 在边界处进行验证。

在遵循这些指南实现了一些(小型)项目并通过各种演讲和视频进行交流之后,我开始看到改进的空间。这些指南本身的改进空间并不大,更多的是它们的表述方式。

  • 这四条语句中有三条是规范性的,但“数据是不可变的”是描述性的。这不仅不一致,一个事实陈述也不适合作为指南。
  • 这些指南没有提到透明度,而透明度对于在对数据进行建模的类之外实现操作至关重要。它也是记录内置透明度的驱动力,因此我认为应该提到它。
  • 我发现另一个重要方面是操作的代表性不足。虽然 Brian 详细解释了操作的放置位置和实现方式,但这些建议并没有明确地包含在原则中。
  • 使非法状态不可表示和在边界处进行验证密切相关。
  • 这些原则的权重并不相等。在介绍它们时,大部分时间都花在了“对数据进行建模,...”(这也是隐含包含如何处理操作的原则)上,之后可以快速地勾选其余三条指南。
  • 总的来说,我认为这些原则的正交性不足。它们的呈现顺序极大地影响了对每个原则的讨论内容,这表明它们彼此之间存在很大依赖性。

如您所见,我对面向数据编程的构建块没有任何(也不存在)问题。我只是觉得它们被组织成四条原则以及它们的标题可以改进。

1.1 版

为了解决上述问题,我做了以下更改

  • 将“数据是不可变的”改为规范性语句,并添加透明度。这使其成为讨论记录的完美载体。
  • 将生成的指南放在第一位,以便在讨论其他特性之前单独讨论记录。
  • 通过将边界验证作为实现不可表示非法状态的策略的一部分,将“在边界处进行验证”纳入“使非法状态不可表示”中。
  • 添加一条关于操作的指南。

这导致了

  • 以不可变且透明的方式对数据进行建模。
  • 对数据进行建模,对所有数据进行建模,并且只对数据进行建模。
  • 使非法状态不可表示。
  • 将操作与数据分离。

1.2 版?

但我对结果仍然不完全满意

  • 正交性几乎没有改善。事实上,我改变了前两个原则的顺序,这仅仅表明它们仍然彼此依赖。
  • 权重分布有所改善,但仍然略有不平衡。以字数作为代理,我们可以看到操作的权重是防止非法状态的三倍(2.6k 字 vs 0.8k 字),尽管这部分是由于缺乏正交性:关于非法状态的文章之所以这么短,是因为我在之前的文章中已经介绍了如何使用密封类型和记录来防止许多非法组合。
  • “对数据进行建模,对所有数据进行建模,并且只对数据进行建模”听起来很酷,但它并不特别引人注目或精确。事实上,您几乎可以在该标题下讨论任何内容。我想知道这是否是一个作家偶尔需要杀死的宠儿。

新版本可能还有更多问题,在这种情况下,我相信进一步对面向数据编程进行实验或接触将使这些问题浮出水面。如果您认为有任何可以改进的地方,请与我联系 - 我在所有地方都是nipafx

文章系列